home *** CD-ROM | disk | FTP | other *** search
- DEFRAG.C v1.10 Source Code <Program>
- East Bay Ray #1 @9964
- Wed Jan 01 18:18:33 1992
- /* DEFRAGMENT WWIV TYPE-2 MESSAGE BASES */
-
- /* Written by Jeff Garzik (East Bay Ray), 11-24-1991 */
- /* Copyright (c) 1991 Jeff M. Garzik */
- /* Compiled and tested using Borland C++ - Version 2.0 */
- /* License granted to freely distribute without compensation and to */
- /* modify as needed "to get the job done." Use at your own risk. */
- /* Distributed "as is". No warranty or guarantee. */
- /* Cannot be used or sold COMMERCIALLY without prior written permission */
- /* of the author, Jeff Garzik. */
- /* Portions Copyright (c) 1988-1991 by Wayne Bell. */
-
- /* Jeff Garzik v1.00 Initial Release. */
- /* Jeff Garzik v1.10 Searches correct drive for free space. */
- /* Processes command line arguments /E, /C. */
- /* Compresses EMAIL.DAT. */
- /* Processes command line argument /O. */
- /* Prints out report upon completion. */
- /* Removes messages with no text. */
- /* Automated mode support shell added. No */
- /* real code is in place for this one. This */
- /* will be for the "fix" feature in the next */
- /* release of the program. If automated */
- /* mode is on, then the program will not ask */
- /* any questions like FIX does, and will */
- /* simply assume you want these fixed (or */
- /* not fixed, depending on how you set your */
- /* options). */
-
- /* Compile using "bcc -ml defrag.c" */
-
- #include <stdio.h>
- #include <io.h>
- #include <fcntl.h>
- #include <string.h>
- #include <stdlib.h>
- #include <sys\stat.h>
- #include <dos.h>
- #include <alloc.h>
- #include <time.h>
- #include <mem.h>
- #include <dir.h>
- #include <errno.h>
- #include "vardec.h"
-
- #define DEFRAG_VER "1.10"
-
- configrec syscfg;
- statusrec status;
- subboardrec subboards[MAX_SUBS];
- unsigned int num_subs, nummsgs;
- postrec *msgs;
- char gatfn[81];
- short *gat;
- int curdrive, conf_count, conf_scan[MAX_SUBS], scan_email, automated, assume_y;
- long messages, totmsgsize, msg_no_text;
- time_t program_start;
-
-
- /*************************************************************************/
- /****************** Wayne Bell's Code (slightly modified) ****************/
- /*************************************************************************/
-
-
- long dfree(int dr)
- /* returns number of bytes available on specified drive */
- {
- long d;
- struct dfree df;
-
- getdfree(dr,&df);
- d = df.df_avail;
- d *= (df.df_bsec);
- d *= (df.df_sclus);
- if (df.df_sclus<0)
- d = -1.0;
- return(d);
- }
-
-
- void save_status()
- /* saves system status in memory to disk */
- {
- char s[80];
- int statusfile;
-
- sprintf(s,"%sSTATUS.DAT",syscfg.datadir);
- statusfile=open(s,O_RDWR | O_BINARY);
- write(statusfile, (void *)(&status), sizeof(statusrec));
- close(statusfile);
- }
-
-
- void get_status()
- /* retrieves system status from disk into memory */
- {
- char s[81];
- int statusfile;
-
- sprintf(s,"%sSTATUS.DAT",syscfg.datadir);
- statusfile=open(s,O_RDWR | O_BINARY);
- if (statusfile>=0) {
- read(statusfile,(void *)(&status), sizeof(statusrec));
- close(statusfile);
- } else
- status.wwiv_version = 0;
- }
-
-
- void iscan(int b)
- /* loads information about message base #b into memory */
- {
- int f;
- char s[81];
-
- nummsgs = 0;
- sprintf(s, "%s%s.SUB", syscfg.datadir, subboards[b].filename);
- f = open(s, O_BINARY | O_RDWR);
- if (f == -1) {
- f = open(s, O_BINARY | O_RDWR | O_CREAT,S_IREAD | S_IWRITE);
- msgs[0].owneruser = 0;
- write(f, (void *)(&msgs[0]), sizeof(postrec));
- }
- lseek(f, 0L, SEEK_SET);
- nummsgs = (read(f, (void *)(&msgs[0]),255*sizeof(postrec)) / sizeof(postrec))-1;
- nummsgs = msgs[0].owneruser;
- close(f);
- }
-
-
- void savebase(int b)
- /* saves message information in memory to disk */
- {
- int f;
- char s[81];
-
- sprintf(s, "%s%s.SUB", syscfg.datadir, subboards[b].filename);
- f = open(s, O_RDWR | O_BINARY | O_TRUNC | O_CREAT, S_IREAD | S_IWRITE);
- lseek(f, 0L, SEEK_SET);
- msgs[0].owneruser = nummsgs;
- write(f, (void *)(&msgs[0]), ((nummsgs+1) * sizeof(postrec)));
- close(f);
- }
-
-
- int open_file(char *fn)
- /* opens a WWIV Type-2 data file */
- {
- int f,i;
- char s[81];
-
- sprintf(s,"%s%s.DAT",syscfg.msgsdir,fn);
- f=open(s,O_RDWR | O_BINARY);
- if (f<0) {
- f=open(s,O_RDWR | O_BINARY | O_CREAT, S_IREAD | S_IWRITE);
- for (i=0; i<2048; i++)
- gat[i]=0;
- write(f,(void *)gat,4096);
- strcpy(gatfn,fn);
- /* chsize(f,4096L + (75L * 1024L)); */
- }
- if (strcmp(gatfn,fn)) {
- lseek(f,0L,SEEK_SET);
- read(f,(void *)gat,4096);
- strcpy(gatfn,fn);
- }
- return(f);
- }
-
-
- void remove_link(messagerec *m1, char *aux)
- /* deletes a message */
- {
- messagerec m;
- char s[81],s1[81];
- int f;
- long csec,nsec;
-
- m=*m1;
- strcpy(s,syscfg.msgsdir);
- switch(m.storage_type) {
- case 0:
- case 1:
- ltoa(m.stored_as,s1,16);
- if (m.storage_type==1) {
- strcat(s,aux);
- strcat(s,"\\");
- }
- strcat(s,s1);
- unlink(s);
- break;
- case 2:
- f=open_file(aux);
- csec=m.stored_as;
- while ((csec>0) && (csec<2048)) {
- nsec=(long) gat[csec];
- gat[csec]=0;
- csec=nsec;
- }
- lseek(f,0L,SEEK_SET);
- write(f,(void *)gat,4096);
- close(f);
- break;
- default:
- /* illegal storage type */
- break;
- }
- }
-
-
- void savefile(char *b, long l1, messagerec *m1, char *aux)
- /* saves a message in memory to disk */
- {
- int f,gatp,i5,i4,gati[128];
- messagerec m;
- char s[81],s1[81];
-
- m=*m1;
- switch(m.storage_type) {
- case 0:
- case 1:
- m.stored_as=status.qscanptr++;
- save_status();
- ltoa(m.stored_as,s1,16);
- strcpy(s,syscfg.msgsdir);
- if (m.storage_type==1) {
- strcat(s,aux);
- strcat(s,"\\");
- }
- strcat(s,s1);
- f=open(s,O_RDWR | O_CREAT | O_BINARY,S_IREAD | S_IWRITE);
- write(f, (void *)b,l1);
- close(f);
- break;
- case 2:
- f=open_file(aux);
- gatp=0;
- i5=(int) ((l1 + 511L)/512L);
- i4=1;
- while ((gatp<i5) && (i4<2048)) {
- if (gat[i4]==0)
- gati[gatp++]=i4;
- ++i4;
- }
- gati[gatp]=-1;
- for (i4=0; i4<i5; i4++) {
- lseek(f,4096L + 512L * (long)(gati[i4]),SEEK_SET);
- write(f,(void *)(&b[i4*512]),512);
- gat[gati[i4]]=gati[i4+1];
- }
- lseek(f,0L,SEEK_SET);
- write(f,(void *)gat,4096);
- close(f);
- m.stored_as=(long) gati[0];
- break;
- case 255:
- f=open(aux,O_RDWR | O_CREAT | O_BINARY,S_IREAD | S_IWRITE);
- write(f, (void *)b,l1);
- close(f);
- break;
- default:
- /* printf("Illegal storage type of %u on save!", m.storage_type); */
- break;
- }
- farfree((void *)b);
- *m1=m;
- }
-
-
- char *readfile(messagerec *m1, char *aux, long *l)
- /* reads a message from disk into memory */
- {
- int f,i,i1,csec;
- long l1,l2;
- char *b,s[81],s1[81];
- messagerec m;
-
- *l=0L;
- m=*m1;
- switch(m.storage_type) {
- case 0:
- case 1:
- strcpy(s,syscfg.msgsdir);
- ltoa(m.stored_as,s1,16);
- if (m.storage_type==1) {
- strcat(s,aux);
- strcat(s,"\\");
- }
- strcat(s,s1);
- f=open(s,O_RDONLY | O_BINARY);
- if (f==-1) {
- *l=0L;
- return(NULL);
- }
- l1=filelength(f);
- if ((b=farmalloc(l1))==NULL) {
- close(f);
- return(NULL);
- }
- read(f,(void *)b,l1);
- close(f);
- *l=l1;
- break;
- case 2:
- f=open_file(aux);
- csec=m.stored_as;
- l1=0;
- while ((csec>0) && (csec<2048)) {
- l1+=512L;
- csec=gat[csec];
- }
- if (!l1) {
- /* printf("\nNo message found.\n\n"); */
- return(NULL);
- }
- if ((b=farmalloc(l1))==NULL)
- return(NULL);
- csec=m.stored_as;
- l1=0;
- while ((csec>0) && (csec<2048)) {
- lseek(f,4096L + 512L*csec,SEEK_SET);
- l1+=(long)read(f,(void *)(&(b[l1])),512);
- csec=gat[csec];
- }
- close(f);
- l2=l1-512;
- while ((l2<l1) && (b[l2]!=26))
- ++l2;
- *l=l2;
- break;
- case 255:
- f=open(aux,O_RDONLY | O_BINARY);
- if (f==-1) {
- *l=0L;
- return(NULL);
- }
- l1=filelength(f);
- if ((b=farmalloc(l1+256L))==NULL)
- return(NULL);
- read(f,(void *)b,l1);
- close(f);
- *l=l1;
- break;
- default:
- /* illegal storage type */
- *l=0L;
- b=NULL;
- break;
- }
- return(b);
- }
-
-
- /*************************************************************************/
- /****************** Wayne Bell's Code (slightly modified) ****************/
- /*************************************************************************/
-
-
- int get_next_email(int inf, int outf, mailrec *m)
- {
- int rc=1;
- mailrec m1, m2;
- long l, l1;
-
- read(inf, (void *)(&m1), sizeof(mailrec));
- if (m1.status & status_multimail) {
- lseek(outf, 0, SEEK_SET);
- l = filelength(outf) / sizeof(mailrec);
- l1 = 0;
- while (l1 < l) {
- l1++;
- read(outf, (void *)(&m2), sizeof(mailrec));
- if (m2.msg.stored_as == m1.msg.stored_as)
- l1 = 0xFFFFFFFF;
- }
- lseek(outf, 0, SEEK_END);
- }
- if (l1 == 0xFFFFFFFF)
- rc = 0;
- *m = m1;
- return(rc);
- }
-
-
- void defrag_email()
- {
- char s[81], s1[81], s2[81], *temp_msg_buf;
- int f, f1, f2, i, i1, i2;
- long len, num_email;
- mailrec mr;
-
- printf("Reading EMAIL.DAT...\r");
- sprintf(s1, "%sTEMP$$$!.DAT", syscfg.msgsdir);
- unlink(s1);
- sprintf(s1, "%sTEMP$$$!.DAT", syscfg.datadir);
- unlink(s1);
- sprintf(s, "%sEMAIL.DAT", syscfg.datadir);
- f1 = open(s, O_RDWR | O_BINARY);
- if (f1 < 0) {
- printf("%s NOT FOUND.\n", s);
- exit(1);
- }
- num_email = (filelength(f1) / sizeof(mailrec));
- sprintf(s1, "%sTEMP$$$!.DAT", syscfg.datadir);
- f2 = open(s1, O_RDWR | O_CREAT | O_BINARY | O_TRUNC, S_IREAD | S_IWRITE);
- if (f2 < 0) {
- printf("%s NOT CREATED.\n", s);
- close(f1);
- exit(1);
- }
- i1 = 0;
- f = open_file("EMAIL");
- if ((dfree(curdrive) > filelength(f)) && (f > 0)) {
- close(f);
- for (i1 = 0; i1 < num_email; i1++) {
- printf("De-fragging EMAIL.DAT (%d/%d)...\r", (i1 + 1), num_email);
- if (get_next_email(f1, f2, &mr))
- if ((mr.touser != 0) || (mr.tosys != 0)) {
- temp_msg_buf = readfile(&mr.msg, "EMAIL", &len);
- if (temp_msg_buf != NULL) {
- totmsgsize += len;
- savefile(temp_msg_buf, len, &mr.msg, "TEMP$$$!");
- } else {
- msg_no_text++;
- mr.touser = 0;
- mr.tosys = 0;
- }
- }
- messages++;
- if ((mr.touser != 0) || (mr.tosys != 0))
- write(f2, (void *)(&mr), sizeof(mailrec));
- }
- sprintf(s, "%sEMAIL.DAT", syscfg.msgsdir);
- sprintf(s1, "%sTEMP$$$!.DAT", syscfg.msgsdir);
- unlink(s);
- f = rename(s1, s);
- if (f == 0) {
- printf("\n");
- sprintf(s, "%sEMAIL.DAT", syscfg.datadir);
- sprintf(s1, "%sTEMP$$$!.DAT", syscfg.datadir);
- unlink(s);
- f = rename(s1, s);
- if (f != 0) {
- printf("De-fragging EMAIL.DAT (ERROR!)... \n");
- switch(errno) {
- case ENOENT:
- strcpy(s2, "No such file");
- break;
- case EACCES:
- strcpy(s2, "Permission denied");
- break;
- case ENOTSAM:
- strcpy(s2, "Not same device");
- break;
- }
- printf(" (Could not rename temporary file; REASON: %s\n", s2);
- unlink(s1);
- sprintf(s, "%sEMAIL.DAT", syscfg.msgsdir);
- unlink(s);
- }
- } else {
- printf("De-fragging EMAIL.DAT (ERROR!)... \n");
- switch(errno) {
- case ENOENT:
- strcpy(s2, "No such file");
- break;
- case EACCES:
- strcpy(s2, "Permission denied");
- break;
- case ENOTSAM:
- strcpy(s2, "Not same device");
- break;
- }
- printf(" (Could not rename temporary file; REASON: %s\n", s2);
- unlink(s1);
- sprintf(s, "%sEMAIL.DAT", syscfg.datadir);
- sprintf(s1, "%sTEMP$$$!.DAT", syscfg.datadir);
- unlink(s);
- unlink(s1);
- }
- } else {
- if (f > 0)
- close(f);
- printf("Reading EMAIL.DAT (NOT ENOUGH DISK SPACE!)...\n");
- }
- }
-
-
- void delete(int mn)
- {
- int i;
-
- if ((mn > 0) && (mn <= nummsgs)) {
- for (i = mn; i < nummsgs; i++)
- msgs[i] = msgs[i + 1];
- nummsgs--;
- }
- }
-
-
- void defrag(int b)
- {
- char s[81], s1[81], s2[81], *temp_msg_buf;
- int f, i, i1, i2;
- long len;
-
- printf("Reading %s...\r", subboards[b].name);
- sprintf(s1, "%sTEMP$$$!.DAT", syscfg.msgsdir);
- unlink(s1);
- iscan(b);
- i1 = 0;
- if (subboards[b].storage_type == 2) {
- f = open_file(subboards[b].filename);
- if ((dfree(curdrive) > filelength(f)) && (f > 0)) {
- close(f);
- for (i1 = 1; i1 <= nummsgs; i1++) {
- temp_msg_buf = readfile(&msgs[i1].msg, subboards[b].filename, &len);
- if (temp_msg_buf != NULL) {
- savefile(temp_msg_buf, len, &msgs[i1].msg, "TEMP$$$!");
- totmsgsize += len;
- } else {
- delete(i1);
- msg_no_text++;
- }
- messages++;
- printf("De-fragging %s (%d/%d)...\r", subboards[b].name, i1, nummsgs);
- }
- sprintf(s, "%s%s.DAT", syscfg.msgsdir, subboards[b].filename);
- sprintf(s1, "%sTEMP$$$!.DAT", syscfg.msgsdir);
- unlink(s);
- f = rename(s1, s);
- if (f == 0) {
- printf("\n");
- savebase(b);
- } else {
- printf("De-fragging %s (ERROR!)... \n", subboards[b].name);
- switch(errno) {
- case ENOENT:
- strcpy(s2, "No such file");
- break;
- case EACCES:
- strcpy(s2, "Permission denied");
- break;
- case ENOTSAM:
- strcpy(s2, "Not same device");
- break;
- }
- printf(" (Could not rename temporary file; REASON: %s\n", s2);
- unlink(s);
- unlink(s1);
- sprintf(s, "%s%s.SUB", syscfg.datadir, subboards[b].filename);
- unlink(s);
- }
- } else {
- if (f > 0)
- close(f);
- printf("Reading %s (NOT ENOUGH DISK SPACE!)...\n", subboards[b].name);
- }
- } else {
- printf("Reading %s...Ignored. (Storage type not 2)\n", subboards[b].name);
- }
- }
-
-
- void report()
- {
- time_t end_run;
-
- printf("\n\n");
- printf("========================================\n");
- printf("%10ld messages processed.\n", messages);
- printf("%10ld bytes (%ldk) processed.\n", totmsgsize);
- printf("%10ld bytes per average message.\n", (totmsgsize / messages));
- time(&end_run);
- printf("%10ld seconds elapsed.\n", (end_run - program_start));
- if (msg_no_text)
- printf("%10ld message(s) with no text removed.\n", msg_no_text);
- printf("========================================\n\n");
- }
-
-
- void main(int argc, char *argv[])
- {
- char s[81], s1[81], s2[81], ch;
- int f, i, i1, i2;
- long len;
-
- time(&program_start);
- conf_count = 0;
- scan_email = 0;
- messages = 0;
- totmsgsize = 0;
- msg_no_text = 0;
- automated = 0;
- assume_y = 0;
- printf("\nDeFrag v%s - Defragment (compress) WWIV type-2 message bases\n", DEFRAG_VER);
- printf("Copyright (c) 1991 by Jeff Garzik\n\n");
- sprintf(s, "CONFIG.DAT");
- f = open(s, O_RDWR | O_BINARY);
- if (f < 0) {
- printf("%s NOT FOUND.\n", s);
- exit(1);
- }
- read(f, (void *)(&syscfg), sizeof(configrec));
- close(f);
- get_status();
- if (status.wwiv_version == 0) {
- printf("STATUS.DAT NOT READ.\n");
- exit(1);
- }
- itoa(status.wwiv_version, s, 10);
- s[5] = s[4];
- s[4] = s[3];
- s[3] = s[2];
- s[2] = s[1];
- s[1] = '.';
- printf("Compiled under %s, running under WWIV v%s.\n\n", VERSION_NUMBER, s);
- sprintf(s, "%sSUBS.DAT", syscfg.datadir);
- f = open(s, O_RDWR | O_BINARY);
- if (f < 0) {
- printf("%s NOT FOUND.\n", s);
- exit(1);
- }
- num_subs = (read(f, subboards, (MAX_SUBS*sizeof(subboardrec))))/
- sizeof(subboardrec);
- close(f);
- if (num_subs < 1) {
- printf("No subs to compress.\n");
- exit(1);
- }
- for (i=1; i<argc; i++) {
- strcpy(s,argv[i]);
- if ((s[0]=='-') || (s[0]=='/')) {
- ch = toupper(s[1]);
- switch(ch) {
- case 'A': /* enable/disable unattended mode */
- switch (s[2]) {
- case 0:
- case '+':
- automated = 1;
- break;
- case '-':
- automated = 0;
- break;
- }
- break;
- case 'C': /* select subs to defrag */
- if (conf_count < 0)
- conf_count = 0;
- i1 = atoi(&(s[2]));
- if ((conf_count == 0) && (i1 >= 0) && (i1 < num_subs)) {
- conf_scan[conf_count] = i1;
- conf_count++;
- } else {
- for (i2 = 0; i2 < conf_count; i2++)
- if (conf_scan[i2] == i1)
- break;
- if (i2 >= conf_count) {
- conf_scan[conf_count] = i1;
- conf_count++;
- }
- }
- break;
- case 'E': /* enable/disable EMAIL.DAT defrag */
- switch (s[2]) {
- case 0:
- case '+':
- scan_email = 1;
- break;
- case '-':
- scan_email = 0;
- break;
- }
- break;
- case 'O': /* only scan EMAIL.DAT */
- conf_count = -1;
- scan_email = 1;
- break;
- case 'Y': /* How to answer Y/N questions */
- switch (s[2]) { /* in unattended mode */
- case 0:
- case '+':
- assume_y = 1;
- break;
- case '-':
- assume_y = 0;
- break;
- }
- break;
- }
- }
- }
- msgs = (postrec *)farmalloc((long)(255 * sizeof(postrec)));
- if (msgs == NULL) {
- printf("Not enough memory.\n");
- exit(1);
- }
- gat = (short *)farmalloc(2048 * sizeof(short));
- if (gat == NULL) {
- printf("Not enough memory.\n");
- exit(1);
- }
- if (syscfg.msgsdir[1] == ':')
- curdrive = (int)(syscfg.msgsdir[0] - 'A' + 1);
- else
- curdrive = getdisk();
- if (scan_email)
- defrag_email();
- if (conf_count == 0) {
- for (i = 0; i < num_subs; i++)
- defrag(i);
- } else {
- for (i = 0; i < conf_count; i++)
- defrag(conf_scan[i]);
- }
- report();
- }
-